package com.yanqu.road.queue;

import com.yanqu.road.enums.eClientLogUploadEventType;
import com.yanqu.road.logic.controller.ClientLog;
import com.yanqu.road.logic.service.impl.ClientLogImpl;
import com.yanqu.road.thinkdata.ThinkingProvider;
import com.yanqu.road.utils.ConfigHelper;
import org.apache.commons.collections.CollectionUtils;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @Author wpj
 * @Date 2020/11/30
 */

@Component
public class ClientLogMgr {
    public static List<ClientLog> clientLogList = new ArrayList<>();

    private static ClientLogMgr clientLogMgr;

    private static final Logger logger = LogManager.getLogger(ClientLogMgr.class.getName());

    public static ThinkingProvider provider;

    @PostConstruct
    public void init() {
        clientLogMgr = this;
        //7.3新增 logAnalysis启动配置加
        //tda.path=./tda.properties 可加可不加 加了consumer=collect
        //tkUrl=http://localhost:9998/Web/sys_service 指向数据收集
        String tkUrl = ConfigHelper.getValue("tkUrl");
        System.err.println("thinkData url is "+tkUrl);
        refreshUrl(tkUrl);

    }

    @Autowired
    private ClientLogImpl clientLog;

    public boolean refreshUrl(String url){
        ThinkingProvider old = provider;
        if (url == null){
            provider = new ThinkingProvider(logger, ConfigHelper.getValue("tkUrl"));
        }else {
            provider = new ThinkingProvider(logger, url);
        }
        try{
            provider.init();
        }catch (Exception e){
            logger.info("error:", e);
        }


        if (old !=null){
            old.flush();
        }
        return true;
    }

    public static void addClientLog(ClientLog clientLog){
        synchronized (clientLogList) {
            clientLogList.add(clientLog);
        }
    }


    public static void addClientLog(List<ClientLog> clientLogs){
        synchronized (clientLogList) {
            clientLogList.addAll(clientLogs);
        }
    }


    public static void save() {
        if (!CollectionUtils.isEmpty(clientLogList)) {
            List<ClientLog> list;
            synchronized (clientLogList) {
                list = new ArrayList<>(clientLogList);
                clientLogList.clear();
                logger.info("save size : {}", list.size());
            }
            int size = 0;
            List<ClientLog> tempList = new ArrayList<>();
            for (ClientLog clientLog : list) {
                tempList.add(clientLog);
                if (tempList.size() >= 5000) {
                    clientLogMgr.clientLog.save(tempList);
                    size += tempList.size();
                    sendClientTrackLog(tempList);
                    tempList = new ArrayList<>();
                }
            }
            if (tempList.size() > 0) {
                clientLogMgr.clientLog.save(tempList);
                sendClientTrackLog(tempList);
                size += tempList.size();
            }
            logger.info("save real size : {}",  size);
        }
    }

    public static void sendClientTrackLog(List<ClientLog> clientLogs){
        logger.info("sendTrackLog start LogsMap size :{}", clientLogs.size());
        for (ClientLog clientLog : clientLogs) {
            if (clientLog == null) {
                continue;
            }
            //只有在这里面的事件需要上传  或者客户端告知要上传数数   ,,兼容一下旧版本,万一客户端没改就炸了
            if (eClientLogUploadEventType.forValue(clientLog.getEventID()) != null || clientLog.isUploadThinking()) {
                Map<String, Object> clientLogDataMap = getStringObjectMap(clientLog);
                trace("guide_complete",clientLogDataMap);
            }
        }
    }

    private static Map<String, Object> getStringObjectMap(ClientLog clientLog) {
        Map<String, Object> clientLogDataMap = new HashMap<>();
        clientLogDataMap.put("#os", clientLog.getOs()==null?"":clientLog.getOs());
        clientLogDataMap.put("pid", clientLog.getChannelID()== null?"":clientLog.getChannelID());
        clientLogDataMap.put("package_id", clientLog.getPackageID()==null?"0":clientLog.getPackageID());
        clientLogDataMap.put("userid_id", clientLog.getUserID()==null?"0":clientLog.getUserID());
        clientLogDataMap.put("open_id", clientLog.getOpenID()==null?"":clientLog.getOpenID());
        clientLogDataMap.put("loginid", clientLog.getLoginID()==null?"0":clientLog.getLoginID());
        clientLogDataMap.put("guide_step", clientLog.getEventID()==null?"":clientLog.getEventID());
        return clientLogDataMap;
    }

    public static void trace(String eventName, Map<String, Object> dataMap) {
        try {
            if(dataMap == null){
                return;
            }

            provider.track(
                    String.valueOf(dataMap.get("userid_id")),
                    String.valueOf(dataMap.get("loginid")),
                    eventName,
                    dataMap);
        }catch (Exception e){
            logger.info("error:", e);
        }

    }

    public static boolean stop() {
        if(provider != null) {
            provider.flush();
            provider.close();
        }
        return true;
    }

    /**
     * 定时发送
     */
    public static void flush(){
        if(provider != null){
            logger.info("provider {}", provider.getClass().getSimpleName());
            provider.flush();
        }
    }
}
